package com.wkbb.sports.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;

import com.github.pagehelper.PageInfo;
import com.wkbb.common.base.BaseController;
import com.wkbb.common.dto.basic.StudentFaceRecognition;
import com.wkbb.common.dto.basic.StudentInfoDto;
import com.wkbb.common.handler.JsonUtil;
import com.wkbb.common.utils.*;
import com.wkbb.sports.dto.*;
import com.wkbb.sports.mapper.TeachFileMapper;
import com.wkbb.sports.model.HlifeBanner;
import com.wkbb.sports.mapper.HlifeBannerMapper;
import com.wkbb.sports.model.*;
import com.wkbb.sports.service.*;
import com.wkbb.sports.utils.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import com.aliyuncs.exceptions.ClientException;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.constants.RedisKeyConstant;
import com.wkbb.common.constants.VersionConstant;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.UserDto;
import com.wkbb.common.enums.SmsTypeEnum;
import com.wkbb.common.redis.RedisTemplateUtil;
import com.wkbb.sports.feign.BasicFeignService;
import com.wkbb.sports.utils.SendSmsUtil;
import com.wkbb.sports.utils.WxPhoneNumberAESUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson.JSONObject;

@RestController
@Api(description = "微信小程序")
@RequestMapping("/sports/{apiVersion}/weixin")
@Slf4j
public class WeixinController extends BaseController {

    @Autowired
    PracticeService practiceService;
    @Autowired
    CourseService courseService;
    @Autowired
    private WorkService workService;
    @Autowired
    private HlifeBannerMapper hlifeBannerMapper;
    @Autowired
    private TeachFileMapper teachFileMapper;

    @Autowired
    BasicFeignService basicFeignService;
    @Autowired
    AccountService accountService;
    @Autowired
    private DetectService detectService;
    @Autowired
    private TeachFileService teachFileService;
    @Autowired
    private RedisTemplateUtil redisTemplateUtil;

    //时时练
    public static final String wechatAppId = "wxfb9f17295963fe88";
    public static final String wechatSecretKey = "876c70e30d694faf5c55ccb6b0c128cd";
    //消息加密密钥
    public static final String encodingAESKey = "27t06w7cu5TBmc2k6YY6a0ijVF47NdXqZvYVOIQaNGE";
    //因时体测
    public static final String appId = "wx6177c5b3e51c98e1";
    public static final String secret = "7ff0cdfbc0b90b9ee390bc10191cb6e3";

    //博研
    public static final String appIdBy = "wx4f696e936979c1be";
    public static final String secretBy = "1253d172323464e5669ce208b1236d57";

    @ApiOperation(value = "提交学生人脸识别数据")
    @RequestMapping(value = "insertStudentFaceRecognition", method = RequestMethod.POST)
    public ResultDTO<?> insertHlifeStudentPractice(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @Valid @RequestBody StudentFaceRecognition data){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        try {
            if (data.getStudentId() == null || StringUtils.isEmpty(data.getStudentName()) || StringUtils.isEmpty(data.getIdCard()) || StringUtils.isEmpty(data.getFaceImgUrl())){
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }
            return basicFeignService.insertStudentFaceRecognition(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResultDTO<>(false);
    }

    @ApiOperation(value = "微信消息")
    @GetMapping(value = "/receiveWechatMessages")
    public String receiveWechatMessages(@ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
                                        @ApiParam(value = "微信加密签名", defaultValue = "1") @RequestParam(name = "signature") String signature,
                                                                   @ApiParam(value = "时间戳", defaultValue = "10") @RequestParam(name = "timestamp") String timestamp,
                                                                    @ApiParam(value = "随机数", defaultValue = "1") @RequestParam(name = "nonce") String nonce,
                                                                   @ApiParam(value = "随机字符串", defaultValue = "1") @RequestParam(name = "echostr") String echostr){
        return "success";
    }



    @ApiOperation(value = "更换手机号")
    @PostMapping(value = "/changeMobile")
    public ResultDTO<?> changeMobile(@ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
                                            @ApiParam(value = "手机号码", required = true) @RequestParam(name = "mobile", required = true) String mobile,
                                            @ApiParam(value = "4位数的短信验证码", required = true) @RequestParam(name = "smsCode", required = true) String smsCode) {
        try {
            UserDto userDto = this.getRouteUserByUnion();
            if (null == userDto) {
                return new ResultDTO(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
            }
            ResultDTO resultDTO = verifyCode(mobile, smsCode);
            if (!resultDTO.isSuccess()) {
                return resultDTO;
            }
            String key = RedisKeyConstant.WKBB_TC_SMS_VERIFY + "type:" + SmsTypeEnum.PERSONAL_CENTER.getValue() + ":mobile:" + mobile;
            redisTemplateUtil.delete(key);
            userDto.setMobile(mobile);
            return basicFeignService.changeMobile(userDto);
        } catch (Exception e) {
            log.error("登录(login)接口异常:", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "推荐教学视频列表")
    @GetMapping(value = "/getTeachVideos")
    public ResultDTO<PageInfo<TeachFileDto>> getTeachVideos(@ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
                                       @ApiParam(value = "分页数", defaultValue = "1") @RequestParam(name = "pageNo") int pageNo,
                                       @ApiParam(value = "分页大小", defaultValue = "10") @RequestParam(name = "pageSize") int pageSize) {
//        UserDto userDto = this.getRouteUserByUnion();
//        if (null == userDto) {
//            return new ResultDTO(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
//        }
        Map<String,Object>  map  = new HashMap<>();
        map.put("terminal", 1);
        map.put("orders", 1);
        PageInfo<TeachFileDto> dtos = null;
        try {
            dtos = teachFileService.getListByPage(map,pageNo,pageSize);
            return new ResultDTO<>(dtos);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "获取学生二维码（用于扫码绑定）")
    @GetMapping(value = "/getBindQRCode")
    public ResultDTO<?> getBindQRCode(@ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
                                      @ApiParam(value = "学生ID", required = true) @RequestParam(name = "studentId", required = true) Long studentId) {
        try {
            UserDto userDto = this.getRouteUserByUnion();
            if (null == userDto) {
                return new ResultDTO(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
            }
            ResultDTO<StudentInfoDto> resultDTO = basicFeignService.getStudentByFamily(studentId,userDto.getId());
            if (resultDTO.isSuccess()){
                StudentInfoDto studentInfoDto = resultDTO.getData();
                String tokenRedisKey = RedisKeyConstant.WKBB_BASIC_USER_ROUTE + RedisKeyConstant.WKBB_BASIC_STU_ROUTE_TOKEN_UNIONID;
                String key = TokenUtil.defaultInstance.getToken(System.currentTimeMillis() + studentInfoDto.getUserId().toString());
                String userTokenRedisKey = String.format(tokenRedisKey, key);
                redisTemplateUtil.set(userTokenRedisKey,studentInfoDto,RedisKeyConstant.EXPIRATION_TIME_24_HOUR);
                return ResultDTO.successResult(key);
            }
            return resultDTO;
        } catch (Exception e) {
            log.error("登录(login)接口异常:", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "扫码绑定学生（获取用户信息）")
    @GetMapping(value = "/getStudentByQRCode")
    public ResultDTO<StudentInfoDto> getStudentByQRCode(@ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
                                      @ApiParam(value = "二维码识别key", required = true) @RequestParam(name = "key", required = true) String key) {
        try {
            UserDto userDto = this.getRouteUserByUnion();
            if (null == userDto) {
                return new ResultDTO(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
            }
            String tokenRedisKey = RedisKeyConstant.WKBB_BASIC_USER_ROUTE + RedisKeyConstant.WKBB_BASIC_STU_ROUTE_TOKEN_UNIONID;
            String userTokenRedisKey = String.format(tokenRedisKey, key);
            StudentInfoDto studentInfoDto = (StudentInfoDto) redisTemplateUtil.get(userTokenRedisKey);
            if (studentInfoDto == null){
                return ResultDTO.errorResult("二维码错误或已失效");
            }
            return ResultDTO.successResult(studentInfoDto);
        } catch (Exception e) {
            log.error("登录(login)接口异常:", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "扫码绑定学生（立即加入）")
    @PostMapping(value = "/bindStudentByQRCode")
    public ResultDTO<StudentInfoDto> bindStudentByQRCode(@ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
                                      @ApiParam(value = "二维码识别key", required = true) @RequestParam(name = "key", required = true) String key) {
        try {
            UserDto userDto = this.getRouteUserByUnion();
            if (null == userDto) {
                return new ResultDTO(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
            }
            String tokenRedisKey = RedisKeyConstant.WKBB_BASIC_USER_ROUTE + RedisKeyConstant.WKBB_BASIC_STU_ROUTE_TOKEN_UNIONID;
            String userTokenRedisKey = String.format(tokenRedisKey, key);
            StudentInfoDto studentInfoDto = (StudentInfoDto) redisTemplateUtil.get(userTokenRedisKey);
            if (studentInfoDto == null){
                return ResultDTO.errorResult("二维码错误或已失效");
            }
            ResultDTO<StudentInfoDto> resultDTO = basicFeignService.bindStudentByQRCode(userDto.getMobile(),userDto.getId(),studentInfoDto);
            return resultDTO;
        } catch (Exception e) {
            log.error("登录(login)接口异常:", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "家长绑定学生")
    @PostMapping(value = "/bindStudent")
    public ResultDTO<StudentInfoDto> bindStudent(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学号", required = false) @RequestParam(name = "studentNo", required = false) String studentNo,
            @ApiParam(value = "姓名", required = true) @RequestParam(name = "studentName", required = true) String studentName,
            @ApiParam(value = "班级邀请码", required = true) @RequestParam(name = "inviteCode", required = true) String inviteCode) {
        try {
            UserDto userDto = this.getRouteUserByUnion();
            if (null == userDto) {
                return new ResultDTO(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
            }
            if (studentName != null) studentName=studentName.trim();
            if (StringUtil.isEmpty(studentNo)) studentNo = null; else studentNo = studentNo.trim();
            if (inviteCode != null) inviteCode=inviteCode.trim();
            return basicFeignService.bindStudent(studentNo,studentName , inviteCode, userDto.getMobile(), userDto.getId());
        } catch (Exception e) {
            log.error("登录(login)接口异常:", e);
            return new ResultDTO(false);
        }
    }

    public static void main(String[] args) {
        String a = " aaa";
        a.trim();
        System.out.println(a);
    }

    @ApiOperation(value = "家长解除绑定")
    @PostMapping(value = "/unbindStudent")
    public ResultDTO<StudentInfoDto> unbindStudent(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学生ID", required = true) @RequestParam(name = "studentId", required = true) Long studentId) {
        try {
            UserDto userDto = this.getRouteUserByUnion();
            if (null == userDto) {
                return new ResultDTO(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
            }
            ResultDTO<StudentInfoDto> resultDTO = basicFeignService.getStudentByFamily(studentId,userDto.getId());
            if (resultDTO.isSuccess()){
                return basicFeignService.unbindStudent(studentId, userDto.getId());
            }
            return new ResultDTO<>(ErrorCode.FAMILY_STU_ERROR);
        } catch (Exception e) {
            log.error("登录(login)接口异常:", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "添加学生")
    @PostMapping(value = "/addStudent")
    public ResultDTO<StudentInfoDto> addStudent(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @Valid @RequestBody StudentInfoDto studentInfoDto) {
        try {
            UserDto userDto = this.getRouteUserByUnion();
            if (null == userDto) {
                return new ResultDTO(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
            }
            if (studentInfoDto.getUserType() == null) studentInfoDto.setUserType(1);
            if (studentInfoDto.getUserType() == 1){
                if (StringUtil.isEmpty(studentInfoDto.getName()) || StringUtil.isEmpty(studentInfoDto.getProvinceCode()) ||
                        StringUtil.isEmpty(studentInfoDto.getCityCode()) || StringUtil.isEmpty(studentInfoDto.getAreaCode()) ||
                        StringUtil.isEmpty(studentInfoDto.getOrgName()) || StringUtil.isEmpty(studentInfoDto.getGradeName()) ||
                        studentInfoDto.getGradeId() == null || StringUtil.isEmpty(studentInfoDto.getClassName())){
                    return new ResultDTO(ErrorCode.PARAM_MISSING);
                }
            }
            return basicFeignService.addStudent(userDto.getMobile(), userDto.getId(),studentInfoDto);
        } catch (Exception e) {
            log.error("登录(login)接口异常:", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "修改学生信息")
    @PostMapping(value = "/updateStudent")
    public ResultDTO<StudentInfoDto> updateStudent(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @Valid @RequestBody StudentInfoDto studentInfoDto) {
        try {
            UserDto userDto = this.getRouteUserByUnion();
            if (null == userDto) {
                return new ResultDTO(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
            }

            if (StringUtils.isEmpty(studentInfoDto.getUserId())){
                return new ResultDTO(ErrorCode.PARAM_MISSING);
            }
            ResultDTO<StudentInfoDto> resultDTO = basicFeignService.getStudentByFamily(studentInfoDto.getUserId(), userDto.getId());
            if (resultDTO.isSuccess()){
                return basicFeignService.updateStudentNew(studentInfoDto);
            }
            return resultDTO;
        } catch (Exception e) {
            log.error("登录(login)接口异常:", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "获取七牛上传凭证")
    @GetMapping(value = "getQiniuUpToken")
    public ResultDTO<String> getQiniuUpToken(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        String upToken = QiniuUtil.getInstance().getToken();
        return new ResultDTO<>(upToken);
    }

    @ApiOperation(value = "获取Banner列表")
    @GetMapping(value = "getBannerList")
    public ResultDTO<List<HlifeBanner>> getBannerList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "上架终端：1学生 2家长 3教师 4擂台", required = false) @RequestParam(name = "terminal", required = false) Integer terminal){
        Map<String,Object> map = new HashMap();
        map.put("terminal",terminal);
        return new ResultDTO<>(hlifeBannerMapper.getListByMapParams(map));
    }

    @ApiOperation(value = "获取分享图片")
    @GetMapping(value = "getShareImg")
    public ResultDTO<HlifeBanner> getShareImg(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "分享类型 1跳绳", required = true) @RequestParam(name = "type", required = true) Integer type){
        Map<String,Object> map = new HashMap();
        map.put("type",type);
        return new ResultDTO<>(hlifeBannerMapper.getShareBanner(map));
    }

    @ApiOperation(value = "获取作业已达标/未达标的学生列表")
    @RequestMapping(value = "getUnAndReachStudentList", method = RequestMethod.GET)
    public ResultDTO<Map<String, Object>> getUnAndReachStudentList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "作业ID", required = true) @RequestParam(name = "workId", required = true) String workId,
            @ApiParam(value = "指定日期 例：2022-11-09", required = true) @RequestParam(name = "date", required = true) String date){
        return workService.getWorkStudentByDate(workId,date);
    }

    @ApiOperation(value = "获取作业列表")
    @RequestMapping(value = "getWorkListByStudentId", method = RequestMethod.GET)
    public ResultDTO<PageInfo<WorkDto>> getWorkListByStudentId(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学生ID", required = false) @RequestParam(name = "studentId", required = false) String studentId,
            @ApiParam(value = "作业ID", required = false) @RequestParam(name = "workId", required = false) String workId,
            @ApiParam(value = "达标状态(0未达标，1已达标)", required = false) @RequestParam(name = "reached", required = false) Integer reached,
            @ApiParam(value = "分页数", defaultValue = "1", required = false) @RequestParam(name = "pageNo", defaultValue = "1", required = false) int pageNo,
            @ApiParam(value = "分页大小", defaultValue = "20", required = false) @RequestParam(name = "pageSize", defaultValue = "20", required = false) int pageSize){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        if (StringUtils.isEmpty(studentId)){
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_STU_NOT_EXIST);
        }
        return workService.getWorkListByStudentId(studentId,workId,reached,pageNo,pageSize);
    }

    @ApiOperation(value = "获取学生列表接口")
    @RequestMapping(value = "getStudentInfoByFamily", method = RequestMethod.GET)
    public ResultDTO getStudentInfoByFamily(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        return practiceService.getStudentInfoByFamily(userDto.getId());
    }

    @ApiOperation(value = "学生获取运动关卡列表")
    @RequestMapping(value = "getSportLevelList", method = RequestMethod.GET)
    public ResultDTO<List<HlifeSportLevel>> getSportLevelList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学生ID", required = false) @RequestParam(name = "studentId", required = false) String studentId,
            @ApiParam(value = "项目类型 1跳绳", required = false,defaultValue = "1") @RequestParam(name = "projectKind", required = false) Integer projectKind,
            @ApiParam(value = "关卡类型 （1速度 2耐力 3速度耐力）", required = false,defaultValue = "1") @RequestParam(name = "levelType", required = false) Integer levelType){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        if (StringUtils.isEmpty(studentId)){
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_STU_NOT_EXIST);
        }
        try {
            Map<String,Object>  map  = new HashMap<>();
            map.put("studentId", studentId);
            map.put("projectKind", projectKind);
            map.put("levelType", levelType);
            return ResultDTO.successResult(practiceService.getSportLevelList(map));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResultDTO<>(false);
    }

    @ApiOperation(value = "提交跳绳结果(运动、作业、擂台)")
    @RequestMapping(value = "insertSportPractice", method = RequestMethod.POST)
    public ResultDTO<HlifeStudentPractice> insertHlifeStudentPractice(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @Valid @RequestBody HlifeStudentPractice hlifeStudentPractice){
//        log.error("insertHlifeStudentPractice",JsonUtil.objectToJson(hlifeStudentPractice));
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        try {
            return practiceService.insertHlifeStudentPractice(hlifeStudentPractice, userDto);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResultDTO<>(false);
    }

    @ApiOperation(value = "获取跳绳结果报告")
    @RequestMapping(value = "getSportPractice", method = RequestMethod.GET)
    public ResultDTO<HlifeStudentPractice> getSportPractice(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "编号", required = false) @RequestParam(name = "id", required = false) Long id){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        try {
            return new ResultDTO<>(practiceService.getByPrimaryKey(id));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResultDTO<>(false);
    }

    @ApiOperation(value = "获取学生课堂列表")
    @RequestMapping(value = "getStuCoursePageList", method = RequestMethod.GET)
    public ResultDTO<PageInfo<StuCourseDto>> getStuCoursePageList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学生id", required = false) @RequestParam(name = "studentId", required = false) String studentId,
            @ApiParam(value = "分页数", defaultValue = "1") @RequestParam(name = "pageNo") int pageNo,
            @ApiParam(value = "分页大小", defaultValue = "10") @RequestParam(name = "pageSize") int pageSize){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        if (StringUtils.isEmpty(studentId)){
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_STU_NOT_EXIST);
        }
        Map<String,Object>  map  = new HashMap<>();
        map.put("studentId", studentId);
        try {
            PageInfo<StuCourseDto> page = courseService.getStuCoursePageList(map,pageNo,pageSize);
            return new ResultDTO<>(page);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResultDTO<>(false);
    }

    @ApiOperation(value = "获取学生课堂详情")
    @RequestMapping(value = "getStuCourse", method = RequestMethod.GET)
    public ResultDTO<StuCourseDetailDto> getStuCourse(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "课堂id", required = true) @RequestParam(name = "courseId", required = true) Long courseId,
            @ApiParam(value = "学生id", required = false) @RequestParam(name = "studentId", required = false) String studentId){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        if (StringUtils.isEmpty(studentId)){
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_STU_NOT_EXIST);
        }
        Map<String,Object>  map  = new HashMap<>();
        map.put("studentId", Long.parseLong(studentId));
        map.put("courseId", courseId);
        try {
            StuCourseDetailDto data = courseService.getStuCourse(map);
            return new ResultDTO<>(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResultDTO<>(false);
    }

//    @ApiOperation(value = "查询个人心率结果图表数据（课堂详情-报告）")
//    @RequestMapping(value = "/getStuDetectChartData", method = RequestMethod.GET)
//    public ResultDTO<DetectStuChartDto> getStuDetectChartData(
//            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
//            @ApiParam(value = "监测ID", required = true) @RequestParam(name = "detectId", required = true) Long detectId,
//            @ApiParam(value = "学生ID", required = true) @RequestParam(name = "studentId", required = true) Long studentId) {
//        UserDto userDto = this.getUserByLogin();
//        if (null == userDto) {
//            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
//        }
//        DetectStuChartDto dto = null;
//        try {
//            dto = detectService.getStuDetectChartData(detectId,studentId);
//        } catch (Throwable e) {
//            e.printStackTrace();
//            return new ResultDTO<>(ErrorCode.SYSTEM_ERROR);
//        }
//        return new ResultDTO<>(dto);
//    }

    @ApiOperation(value = "获取运动记录 统计信息")
    @RequestMapping(value = "getStuSportStatistics", method = RequestMethod.GET)
    public ResultDTO<StuSportStatisticsDto> getStuSportStatistics(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学生id", required = false) @RequestParam(name = "studentId", required = false) String studentId,
            @ApiParam(value = "运动项目 1跳绳 ", required = false, defaultValue = "1") @RequestParam(name = "projectKind", required = false) Byte projectKind,
            @ApiParam(value = "年月 例：2021-11", required = false) @RequestParam(name = "date", required = false) String date){
//        UserDto userDto = getRouteUserByUnion();
//        if (null == userDto) {
//            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
//        }
//        if (StringUtils.isEmpty(studentId)){
//            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_STU_NOT_EXIST);
//        }
        return practiceService.getStuSportStatistics(Long.parseLong(studentId), projectKind, date);
    }

    @ApiOperation(value = "获取最近N天运动报告(默认30天)")
    @RequestMapping(value = "getLatelyStuSport", method = RequestMethod.GET)
    public ResultDTO<LatelStuSportDto> getLatelyStuSport(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学生id", required = false) @RequestParam(name = "studentId", required = false) String studentId,
            @ApiParam(value = "运动项目 1跳绳 ", required = false, defaultValue = "1") @RequestParam(name = "projectKind", required = false) Byte projectKind,
            @ApiParam(value = "最近天数,默认30天", required = false,defaultValue = "30") @RequestParam(name = "day", required = false) Integer day){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        if (StringUtils.isEmpty(studentId)){
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_STU_NOT_EXIST);
        }
        Map<String, Object> params = new HashMap<>();
        params.put("studentId", studentId);
        params.put("projectKind", projectKind);
        //1小时内 心率异常 实时参与人数
        if (day == null || day == 0 ) day = 30;
        params.put("beginDate", DateUtil.addCurrDay(-day));
        params.put("endDate", DateUtil.getDate());
        return practiceService.getLatelyStuSport(params);
    }

    @ApiOperation(value = "获取节奏音乐列表")
    @RequestMapping(value = "getMusicList", method = RequestMethod.GET)
    public ResultDTO<List<TrainMusic>> getMusicList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        return ResultDTO.successResult(teachFileMapper.getMusicListByMapParams(null));
    }

    @ApiOperation(value = "获取首页、我的 运动统计信息")
    @RequestMapping(value = "getStuHomeSportStatistics", method = RequestMethod.GET)
    public ResultDTO<StuSportStatisticsDto> getStuHomeSportStatistics(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学生id", required = false) @RequestParam(name = "studentId", required = false) String studentId,
            @ApiParam(value = "运动项目 1跳绳 ", required = false, defaultValue = "1") @RequestParam(name = "projectKind",defaultValue = "1",required = false) Byte projectKind){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        if (StringUtils.isEmpty(studentId)){
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_STU_NOT_EXIST);
        }
        return practiceService.getStuHomeSportStatistics(Long.parseLong(studentId), projectKind);
    }

    @ApiOperation(value = "分页获取运动记录")
    @RequestMapping(value = "getSportPracticePageList", method = RequestMethod.GET)
    public ResultDTO<PageInfo<HlifeStudentPractice>> getSportPracticePageList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学生id", required = false) @RequestParam(name = "studentId", required = false) String studentId,
            @ApiParam(value = "运动项目 1跳绳 ", required = false, defaultValue = "1") @RequestParam(name = "projectKind", required = false) Byte projectKind,
            @ApiParam(value = "年月 例：2021-11", required = false) @RequestParam(name = "date", required = false) String date,
            @ApiParam(value = "分页数", defaultValue = "1") @RequestParam(name = "pageNo") int pageNo,
            @ApiParam(value = "分页大小", defaultValue = "10") @RequestParam(name = "pageSize") int pageSize){
        UserDto userDto = getRouteUserByUnion();
        if (null == userDto) {
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_TOKEN_NOT_EXIST);
        }
        if (StringUtils.isEmpty(studentId)){
            return new ResultDTO<>(ErrorCode.SECURITY_ACCESS_STU_NOT_EXIST);
        }
        Map<String,Object>  map  = new HashMap<>();
        map.put("studentId", studentId);
        map.put("projectKind", projectKind);
        map.put("date", date);
        try {
            PageInfo<HlifeStudentPractice> page = practiceService.getListByPage(map,pageNo,pageSize);
            for (HlifeStudentPractice item:page.getList()){
                switch (item.getModelType()){
                    case 1:item.setModelTypeName("限时模式");break;
                    case 2:item.setModelTypeName("限数模式");break;
                    case 3:item.setModelTypeName("自由模式");break;
                }
            }
            return new ResultDTO<>(page);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResultDTO<>(false);
    }

    @ResponseBody
    @ApiOperation(value = "微信登录")
    @RequestMapping(value = "/wxLogin", method = RequestMethod.POST)
    public ResultDTO<UserDto> wxLogin(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @RequestBody WxEncryptionPhoneInfo encryptionPhoneInfo) {
        try {
            String encryptedData = encryptionPhoneInfo.getEncryptedData();
            String iv = encryptionPhoneInfo.getIv();
            if (null == encryptedData || iv == null) {
                return new ResultDTO(ErrorCode.SECURITY_PARAM_MISSING_DEVICE_CODE);
            }
            if (encryptionPhoneInfo.getAppletType() == null) encryptionPhoneInfo.setAppletType(1);
            //授权（必填）
            String grantType = "authorization_code";
            //////////////// 1、向微信服务器 使用登录凭证 code 获取 session_key 和 openid ////////////////
            Map<String, String> param = null;
            param = new HashMap<>();
            //小程序类型  1（时时练,默认） 2（因时体测） 3 博研时时练
            switch (encryptionPhoneInfo.getAppletType()){
                case 3:
                    param.put("appid", appIdBy);
                    param.put("secret", secretBy);
                    break;
                case 2:
                    param.put("appid", appId);
                    param.put("secret", secret);
                    break;
                default:
                    param.put("appid", wechatAppId);
                    param.put("secret", wechatSecretKey);
                    break;
            }
            param.put("js_code", encryptionPhoneInfo.getCode());
            param.put("grant_type", grantType);
            //发送请求
            log.info("获取小程序授权接口，入参{}", JsonUtil.objectToJson(param));
            String sr = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/jscode2session", param);

            //解析相应内容（转换成json对象）
            JSONObject json = JSONObject.parseObject(sr);
            log.info("获取小程序授权接口，返回值{}", sr);

            //获取会话密钥（session_key）
            String sessionKey = json.getString("session_key");
            if (sessionKey == null){
                return ResultDTO.errorResult(sr);
            }
            String openId = json.getString("openid");
            String unionId = json.getString("unionid");

            //解密
            WxPhoneNumberAESUtil wxPhoneNumberAESUtil = new WxPhoneNumberAESUtil(encryptedData, sessionKey, iv);
            WxPhoneDecryptInfo info = wxPhoneNumberAESUtil.decrypt();
            String mobile = info.getPhoneNumber();
            log.info("小程序解密返回值{}", JsonUtil.objectToJson(info));
            if (StringUtils.isEmpty(mobile)){
                return new ResultDTO(ErrorCode.PARAM_MISMATCH);
            }
            UserDto user = new UserDto();
            user.setUnionId(unionId);
            user.setOpenId(openId);
            user.setMobile(mobile);
            user.setInviterUserId(encryptionPhoneInfo.getInviterUserId());
//            if (encryptionPhoneInfo.getInviterUserId() != null){
//                ResultDTO<UserInfoDto> resultDTO = basicFeignService.getUserById(encryptionPhoneInfo.getInviterUserId());
//                if (resultDTO.isSuccess()){
//                    UserInfoDto userInfoDto = resultDTO.getData();
//                    user.setInviterUserId(encryptionPhoneInfo.getInviterUserId());
//                    user.setMobile(userInfoDto.getMobile());
//                }
//            }
            return basicFeignService.wxLogin(user);
        } catch (Exception e) {
            log.info("微信登录解密手机号异常", e);
        }
        return new ResultDTO(ErrorCode.PARAM_MISMATCH);
    }

    @ResponseBody
    @ApiOperation(value = "微信授权获取openid")
    @RequestMapping(value = "/wxAuthorize", method = RequestMethod.POST)
    public ResultDTO<String> wxAuthorize(
            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
            @RequestBody WxEncryptionPhoneInfo encryptionPhoneInfo) {
        try {
            if (encryptionPhoneInfo.getAppletType() == null) encryptionPhoneInfo.setAppletType(1);
            //授权（必填）
            String grantType = "authorization_code";
            //////////////// 1、向微信服务器 使用登录凭证 code 获取 session_key 和 openid ////////////////
            Map<String, String> param = null;
            param = new HashMap<>();
            switch (encryptionPhoneInfo.getAppletType()){
                case 3:
                    param.put("appid", appIdBy);
                    param.put("secret", secretBy);
                    break;
                case 2:
                    param.put("appid", appId);
                    param.put("secret", secret);
                    break;
                default:
                    param.put("appid", wechatAppId);
                    param.put("secret", wechatSecretKey);
                    break;
            }
            param.put("js_code", encryptionPhoneInfo.getCode());
            param.put("grant_type", grantType);
            //发送请求
            log.info("获取小程序授权接口，入参{}", JsonUtil.objectToJson(param));
            String sr = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/jscode2session", param);
            //解析相应内容（转换成json对象）
            JSONObject json = JSONObject.parseObject(sr);
            String openId = json.getString("openid");
            return ResultDTO.successResult(openId);
        } catch (Exception e) {
            log.info("微信登录解密手机号异常", e);
        }
        return new ResultDTO(ErrorCode.PARAM_MISMATCH);
    }

    @ApiOperation(value = "手机号登录")
    @PostMapping(value = "/loginByMobile")
    public ResultDTO<UserDto> loginByMobile(@ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
        @ApiParam(value = "手机号码", required = true) @RequestParam(name = "mobile", required = true) String mobile,
        @ApiParam(value = "4位数的短信验证码", required = true) @RequestParam(name = "smsCode", required = true) String smsCode,
        @ApiParam(value = "邀请者用户ID", required = false) @RequestParam(name = "inviterUserId", required = false) Long inviterUserId) {
        try {
            //验证短信验证码
            ResultDTO resultDTO = verifyCode(mobile, smsCode);
            if (!resultDTO.isSuccess()) {
                return resultDTO;
            }
            String key = RedisKeyConstant.WKBB_TC_SMS_VERIFY + "type:" + SmsTypeEnum.PERSONAL_CENTER.getValue() + ":mobile:" + mobile;
            redisTemplateUtil.delete(key);

            UserDto user = new UserDto();
            user.setMobile(mobile);
            user.setInviterUserId(inviterUserId);
            return basicFeignService.wxLogin(user);
        } catch (Exception e) {
            log.error("登录(login)接口异常:", e);
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "发送短信验证码")
    @PostMapping(value = "/sendSms")
    public ResultDTO sendSms(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "手机号码", required = true) @RequestParam(name = "mobile", required = true) String mobile
    ) {
        if (!VerifyUtil.isMobileNum(mobile)) {
            return new ResultDTO(ErrorCode.FORMAT_PHONE_ILLEGAL);
        }
        try {
            String code = SendSmsUtil.sendSms(mobile);
            if (!StringUtils.isEmpty(code)) {
                String key = RedisKeyConstant.WKBB_TC_SMS_VERIFY + "type:" + SmsTypeEnum.PERSONAL_CENTER.getValue() + ":mobile:" + mobile;
                redisTemplateUtil.set(key, code, RedisKeyConstant.EXPIRATION_TIME_5);
                return new ResultDTO();
            }
        } catch (ClientException e) {
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
        return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
    }

    /**
     * 校验验证码
     */
    private ResultDTO verifyCode(String mobile, String smsCode) {
        log.info("*****verifyCode*****mobile:{},smsCode:{}", mobile, smsCode);
        if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(smsCode)) {
            return new ResultDTO(ErrorCode.PARAM_MISSING);
        }
        //验证手机号码正确性,验证短信验证码长度(可以不验证),验证不通过返回错误信息
        if (!VerifyUtil.isMobileNum(mobile)) {
            return new ResultDTO(ErrorCode.FORMAT_PHONE_ILLEGAL);
        }
        //从redis中获取短信验证码(发送短信时,验证码和发送时间存于redis中)
        String key = RedisKeyConstant.WKBB_TC_SMS_VERIFY + "type:" + SmsTypeEnum.PERSONAL_CENTER.getValue() + ":mobile:" + mobile;
        String redisCode = "";
        if (null != redisTemplateUtil.get(key)) {
            redisCode = String.valueOf(redisTemplateUtil.get(key));
        }
        log.info("*****verifyCode*****smsCode:{},redisCode:{}", smsCode, redisCode);
        //如果短信验证码不一致,则返回登录失败,手机验证码不正确,请重新输入
        if (org.apache.commons.lang.StringUtils.isEmpty(redisCode)) {
            return new ResultDTO(ErrorCode.COMMON_VALIDATE_CODE_NOT_EXIST_OR_INVALID);
        }
        if (!smsCode.equals(redisCode)) {
            return new ResultDTO(ErrorCode.COMMON_VALIDATE_CODE_NOT_EXIST);
        }
        return new ResultDTO(true);
    }
//
//    //时时练
//    public static final String wechatAppId = "wxfb9f17295963fe88";
//    public static final String wechatSecretKey = "876c70e30d694faf5c55ccb6b0c128cd";
//    //消息加密密钥
//    public static final String encodingAESKey = "27t06w7cu5TBmc2k6YY6a0ijVF47NdXqZvYVOIQaNGE";
//    //因时体测
//    public static final String appId = "wx6177c5b3e51c98e1";
//    public static final String secret = "7ff0cdfbc0b90b9ee390bc10191cb6e3";
//
//    //博研
//    public static final String appIdBy = "wx4f696e936979c1be";
//    public static final String secretBy = "1253d172323464e5669ce208b1236d57";


//    @ResponseBody
//    @ApiOperation(value = "微信授权小程序码")
//    @RequestMapping(value = "/createwxaqrcode", method = RequestMethod.GET)
//    public ResultDTO<String> createwxaqrcode(
//            @ApiParam(value = "接口版本", defaultValue = VersionConstant.V1, required = true) @PathVariable(name = "apiVersion") String apiVersion,
//            @ApiParam(value = "路径", required = true) @RequestParam(name = "path", required = false) String path,
//            @ApiParam(value = "小程序 1时时练 2因时体测 3博研", required = true) @RequestParam(name = "type", required = true) int type) {
//        try {
//            Map<String, String> param = new HashMap<>();
//            switch (type){
//                case 3:
//                    param.put("appid", appIdBy);
//                    param.put("secret", secretBy);
//                    break;
//                case 2:
//                    param.put("appid", appId);
//                    param.put("secret", secret);
//                    break;
//                default:
//                    param.put("appid", wechatAppId);
//                    param.put("secret", wechatSecretKey);
//                    break;
//            }
//            param.put("grant_type","client_credential");
//            //发送请求
////            log.info("获取小程序授权接口，入参{}", JsonUtil.objectToJson(param));
//            String sr = HttpClientUtil.doGet("https://api.weixin.qq.com/cgi-bin/token", param);
//            log.info("获取小程序授权接口，返回值{}", sr);
//
//            //解析相应内容（转换成json对象）
//            JSONObject json = JSONObject.parseObject(sr);
//            String access_token = json.getString("access_token");
//
//            if (StringUtil.isEmpty(path)) path = "pages/meta/index?metaverse=true&location=all";
//            JSONObject data = new JSONObject();
//            data.put("path", path);
//            data.put("width", "430");
//            //发送请求
//            String response = HttpClientUtil.doPostJson("https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token="+access_token, data.toJSONString());
//            return ResultDTO.successResult(response);
//        } catch (Exception e) {
//            log.info("微信登录解密手机号异常", e);
//        }
//        return new ResultDTO(ErrorCode.PARAM_MISMATCH);
//    }
}
